2236
12861
¿Cómo es que ciertas cadenas aleatorias producen colores cuando se ingresan como colores de fondo en HTML? Por ejemplo:
 prueba 
... produce un documento con fondo rojo en todos los navegadores y plataformas.
Curiosamente, mientras que chucknorri también produce un fondo rojo, chucknorr produce un fondo amarillo.
¿Que está pasando aqui? 
Es un vestigio de los días de Netscape:
Los dígitos que faltan se tratan como 0 [...]. Un dígito incorrecto simplemente se interpreta como 0. Por ejemplo, los valores # F0F0F0, F0F0F0, F0F0F, #FxFxFx y FxFxFx son todos iguales.
Es de la publicación del blog Una pequeña perorata sobre el análisis de color de Microsoft Internet Explorer que lo cubre con gran detalle, incluidas diferentes longitudes de valores de color, etc.
Si aplicamos las reglas a su vez de la publicación del blog, obtenemos lo siguiente:
Reemplaza todos los caracteres hexadecimales no válidos por ceros:
chucknorris se convierte en c00c0000000
Rellene hasta el siguiente número total de caracteres divisible por 3 (11 → 12):
c00c 0000 0000
Dividir en tres grupos iguales, con cada componente representando el componente de color correspondiente de un color RGB:
RGB (c00c, 0000, 0000)
Truncar cada uno de los argumentos de la derecha a dos caracteres.
Lo que, finalmente, da el siguiente resultado:
RGB (c0, 00, 00) = # C00000 o RGB (192, 0, 0)
A continuación, se muestra un ejemplo que demuestra el atributo bgcolor en acción para producir esta muestra de color "asombrosa":


 chuck norris 
 Mr T 
 ninjaturtle 


 enfermo 
 crap 
 césped 


Esto también responde a la otra parte de la pregunta: ¿Por qué bgcolor = "chucknorr" produce un color amarillo? Bueno, si aplicamos las reglas, la cadena es:
c00c00000 => c00 c00 000 => c0 c0 00 [RGB (192, 192, 0)]
Lo que le da un color oro amarillo claro. Como la cadena comienza con 9 caracteres, esta vez mantenemos la segunda "C", por lo que termina en el valor de color final.
Originalmente encontré esto cuando alguien señaló que se podía hacer color = "crap" y, bueno, sale marrón.
|
Lamento no estar de acuerdo, pero de acuerdo con las reglas para analizar un valor de color heredado publicado por @Yuhong Bao, chucknorris NO equivale a # CC0000, sino a # C00000, un tono de rojo muy similar pero ligeramente diferente. Usé el complemento Firefox ColorZilla para verificar esto.
Las reglas establecen:
haz que la cuerda tenga una longitud que sea múltiplo de 3 agregando 0s: chucknorris0
separe la cuerda en 3 cuerdas de igual longitud: chuc knor ris0
truncar cada cadena a 2 caracteres: ch kn ri
mantenga los valores hexadecimales y agregue 0 cuando sea necesario: C0 00 00
Pude usar estas reglas para interpretar correctamente las siguientes cadenas:
Amuletos de la suerte
Suerte
LuckBeALady
SuerteBeALadyEsta noche
Estilo Gangnam
ACTUALIZACIÓN: Los respondedores originales que dijeron que el color era # CC0000 han editado sus respuestas para incluir la corrección.
|
La mayoría de los navegadores simplemente ignorarán cualquier valor NO hexadecimal en su cadena de colores, sustituyendo los dígitos que no sean hexadecimales por ceros.
ChuCknorris se traduce como c00c0000000. En este punto, el navegador dividirá la cadena en tres secciones iguales, indicando los valores Rojo, Verde y Azul: c00c 0000 0000. Se ignorarán los bits adicionales en cada sección, lo que hace que el resultado final sea # c00000, que es de color rojizo.
Tenga en cuenta que esto no se aplica al análisis de color CSS, que sigue el estándar CSS.

Rojizo

Igual que arriba

Negro

| ¡La razón es que el navegador no puede entenderlo e intenta traducirlo de alguna manera a lo que puede entender y en este caso a un valor hexadecimal! ... chucknorris comienza con c, que es un carácter reconocido en hexadecimal, ¡también convierte todos los caracteres no reconocidos en 0! Entonces chucknorris en formato hexadecimal se convierte en: c00c00000000, todos los demás caracteres se vuelven 0 yc permanece donde están ... Ahora se dividen por 3 para RGB (rojo, verde, azul) ... R: c00c, G: 0000, B: 0000 ... Pero sabemos que el hexadecimal válido para RGB es solo de 2 caracteres, significa R: c0, G: 00, B: 00 Entonces el resultado real es: bgcolor = "# c00000"; También agregué los pasos en la imagen como una referencia rápida para ti: | El navegador está intentando convertir chucknorris en un código de color hexadecimal porque no es un valor válido. En chucknorris, todo excepto c no es un valor hexadecimal válido. Entonces se convierte a c00c00000000. Que se convierte en # c00000, un tono de rojo. Esto parece ser un problema principalmente con Internet Explorer y Opera (12) ya que tanto Chrome (31) como Firefox (26) simplemente lo ignoran. PD Los números entre paréntesis son las versiones del navegador que probé. En una nota más ligera Chuck Norris no se ajusta a los estándares web. Los estándares web cumplen a él. # BADA55 | La especificación HTML de WHATWG tiene el algoritmo exacto para analizar un color heredadovalor: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value. El código que Netscape Classic utiliza para analizar cadenas de colores es de código abierto: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155. Por ejemplo, observe que cada carácter se analiza como un dígito hexadecimal y luego se cambia a un entero de 32 bits sin verificar el desbordamiento. Solo ocho dígitos hexadecimales caben en un entero de 32 bits, por lo que solo se consideran los últimos 8 caracteres. Después de analizar los dígitos hexadecimales en números enteros de 32 bits, se truncan en números enteros de 8 bits dividiéndolos entre 16 hasta que quepan en 8 bits, razón por la cual se ignoran los ceros iniciales. Actualización: este código no coincide exactamente con lo definido en la especificación, pero la única diferencia es que hay algunas líneas de código. Creo que son estas líneas las que se agregaron (en Netscape 4): si (bytes_por_val> 4) { bytes_per_val = 4; } | Responder: El navegador intentará convertir chucknorris en un valor hexadecimal. Dado que c es el único carácter hexadecimal válido en chucknorris, el valor se convierte en: c00c00000000 (0 para todos los valores que no eran válidos). Luego, el navegador divide el resultado en 3 grupos: Rojo = c00c, Verde = 0000, Azul = 0000. Dado que los valores hexadecimales válidos para fondos html solo contienen 2 dígitos para cada tipo de color (r, g, b), los últimos 2 dígitos se truncan de cada grupo, dejando un valor rgb de c00000, que es un color de tono rojizo. | chucknorris comienza con c, y el navegador lo lee en un valor hexadecimal. Porque A, B, C, D, E y F son caracteres en hexadecimal. El navegador convierte chucknorris en un valor hexadecimal, C00C00000000. Luego, el valor hexadecimal C00C00000000 se convierte a formato RGB (dividido por 3): C00C00000000 ⇒ R: C00C, G: 0000, B: 0000 El navegador solo necesita dos dígitos para indicar el color: R: C00C, G: 0000, B: 0000 ⇒ R: C0, G: 00, B: 00 ⇒ C00000 Finalmente, muestre bgcolor = C00000 en el navegador web. Aquí hay un ejemplo que lo demuestra: chucknorris c00c00000000 c00000 | Las reglas para analizar colores en atributos heredados implican pasos adicionales a los mencionados en las respuestas existentes. El componente truncado a la parte de 2 dígitos se describe como: Descartar todos los personajes excepto los últimos 8 Descarte los ceros iniciales uno por uno siempre que todos los componentes tengan un cero inicial Descartar todos los personajes excepto los 2 primeros Algunos ejemplos: oooFoooFoooF 000F 000F 000F <- reemplazar, rellenar y trocear 0F 0F 0F <- ceros iniciales truncados 0F 0F 0F <- truncado a 2 caracteres desde la derecha oooFooFFoFFF 000F 00FF 0FFF <- reemplazar, rellenar y fragmentar 00F 0FF FFF <- ceros iniciales truncados 00 0F FF <- truncado a 2 caracteres desde la derecha ABCooooooABCooooooABCoooooo ABC000000 ABC000000 ABC000000 <- reemplazar, rellenar y fragmentar BC000000 BC000000 BC000000 <- truncado a 8 caracteres desde la izquierda BC BC BC <- truncado a 2 caracteres desde la derecha AoCooooooAoCooooooAoCoooooo A0C000000 A0C000000 A0C000000 <- reemplazar, rellenar y trocear 0C000000 0C000000 0C000000 <- truncado a 8 caracteres desde la izquierda C000000 C000000 C000000 <- ceros iniciales truncados C0 C0 C0 <- truncado a 2 caracteres desde la derecha A continuación se muestra una implementación parcial del algoritmo. No maneja errores o casos donde el usuario ingresa un color válido. function parseColor (input) { // todo: devuelve el error si la entrada es "" entrada = entrada.trim (); // todo: devuelve el error si la entrada es "transparente" // todo: devuelve el #rrggbb correspondiente si la entrada es un color con nombre // todo: devuelve #rrggbb si la entrada coincide con #rgb // todo: reemplaza los puntos de código Unicode mayores que U + FFFF con 00 if (input.length> 128) { input = input.slice (0, 128); } if (input.charAt (0) === "#") { input = input.slice (1); } input = input.replace (/ [^ 0-9A-Fa-f] / g, "0"); while (input.length === 0 || input.length% 3> 0) { entrada + = "0"; } var r = input.slice (0, input.length / 3); var g = input.slice (input.length / 3, input.length * 2/3); var b = input.slice (input.length * 2/3); if (r.length> 8) { r = r. rebanada (-8); g = g. rebanada (-8); b = b. rebanada (-8); } while (r.length> 2 && r.charAt (0) === "0" && g.charAt (0) === "0" && b.charAt (0) === "0") { r = r. rebanada (1); g = g. rebanada (1); b = b. rebanada (1); } if (r.length> 2) { r = r. rebanada (0, 2); g = g. rebanada (0, 2); b = b. rebanada (0, 2); } return "#" + r.padStart (2, "0") + g.padStart (2, "0") + b.padStart (2, "0"); } $ (función () { $ ("# entrada"). on ("cambiar", función () { var input = $ (esto) .val (); var color = parseColor (entrada); var $ celdas = $ ("# resultado tbody td"); $ cells.eq (0) .attr ("bgcolor", entrada); $ cell.eq (1) .attr ("bgcolor", color); varvalor: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value. El código que Netscape Classic utiliza para analizar cadenas de colores es de código abierto: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155. Por ejemplo, observe que cada carácter se analiza como un dígito hexadecimal y luego se cambia a un entero de 32 bits sin verificar el desbordamiento. Solo ocho dígitos hexadecimales caben en un entero de 32 bits, por lo que solo se consideran los últimos 8 caracteres. Después de analizar los dígitos hexadecimales en números enteros de 32 bits, se truncan en números enteros de 8 bits dividiéndolos entre 16 hasta que quepan en 8 bits, razón por la cual se ignoran los ceros iniciales. Actualización: este código no coincide exactamente con lo definido en la especificación, pero la única diferencia es que hay algunas líneas de código. Creo que son estas líneas las que se agregaron (en Netscape 4): si (bytes_por_val> 4) { bytes_per_val = 4; } | Responder: El navegador intentará convertir chucknorris en un valor hexadecimal. Dado que c es el único carácter hexadecimal válido en chucknorris, el valor se convierte en: c00c00000000 (0 para todos los valores que no eran válidos). Luego, el navegador divide el resultado en 3 grupos: Rojo = c00c, Verde = 0000, Azul = 0000. Dado que los valores hexadecimales válidos para fondos html solo contienen 2 dígitos para cada tipo de color (r, g, b), los últimos 2 dígitos se truncan de cada grupo, dejando un valor rgb de c00000, que es un color de tono rojizo. | chucknorris comienza con c, y el navegador lo lee en un valor hexadecimal. Porque A, B, C, D, E y F son caracteres en hexadecimal. El navegador convierte chucknorris en un valor hexadecimal, C00C00000000. Luego, el valor hexadecimal C00C00000000 se convierte a formato RGB (dividido por 3): C00C00000000 ⇒ R: C00C, G: 0000, B: 0000 El navegador solo necesita dos dígitos para indicar el color: R: C00C, G: 0000, B: 0000 ⇒ R: C0, G: 00, B: 00 ⇒ C00000 Finalmente, muestre bgcolor = C00000 en el navegador web. Aquí hay un ejemplo que lo demuestra: chucknorris c00c00000000 c00000 | Las reglas para analizar colores en atributos heredados implican pasos adicionales a los mencionados en las respuestas existentes. El componente truncado a la parte de 2 dígitos se describe como: Descartar todos los personajes excepto los últimos 8 Descarte los ceros iniciales uno por uno siempre que todos los componentes tengan un cero inicial Descartar todos los personajes excepto los 2 primeros Algunos ejemplos: oooFoooFoooF 000F 000F 000F <- reemplazar, rellenar y trocear 0F 0F 0F <- ceros iniciales truncados 0F 0F 0F <- truncado a 2 caracteres desde la derecha oooFooFFoFFF 000F 00FF 0FFF <- reemplazar, rellenar y fragmentar 00F 0FF FFF <- ceros iniciales truncados 00 0F FF <- truncado a 2 caracteres desde la derecha ABCooooooABCooooooABCoooooo ABC000000 ABC000000 ABC000000 <- reemplazar, rellenar y fragmentar BC000000 BC000000 BC000000 <- truncado a 8 caracteres desde la izquierda BC BC BC <- truncado a 2 caracteres desde la derecha AoCooooooAoCooooooAoCoooooo A0C000000 A0C000000 A0C000000 <- reemplazar, rellenar y trocear 0C000000 0C000000 0C000000 <- truncado a 8 caracteres desde la izquierda C000000 C000000 C000000 <- ceros iniciales truncados C0 C0 C0 <- truncado a 2 caracteres desde la derecha A continuación se muestra una implementación parcial del algoritmo. No maneja errores o casos donde el usuario ingresa un color válido. function parseColor (input) { // todo: devuelve el error si la entrada es "" entrada = entrada.trim (); // todo: devuelve el error si la entrada es "transparente" // todo: devuelve el #rrggbb correspondiente si la entrada es un color con nombre // todo: devuelve #rrggbb si la entrada coincide con #rgb // todo: reemplaza los puntos de código Unicode mayores que U + FFFF con 00 if (input.length> 128) { input = input.slice (0, 128); } if (input.charAt (0) === "#") { input = input.slice (1); } input = input.replace (/ [^ 0-9A-Fa-f] / g, "0"); while (input.length === 0 || input.length% 3> 0) { entrada + = "0"; } var r = input.slice (0, input.length / 3); var g = input.slice (input.length / 3, input.length * 2/3); var b = input.slice (input.length * 2/3); if (r.length> 8) { r = r. rebanada (-8); g = g. rebanada (-8); b = b. rebanada (-8); } while (r.length> 2 && r.charAt (0) === "0" && g.charAt (0) === "0" && b.charAt (0) === "0") { r = r. rebanada (1); g = g. rebanada (1); b = b. rebanada (1); } if (r.length> 2) { r = r. rebanada (0, 2); g = g. rebanada (0, 2); b = b. rebanada (0, 2); } return "#" + r.padStart (2, "0") + g.padStart (2, "0") + b.padStart (2, "0"); } $ (función () { $ ("# entrada"). on ("cambiar", función () { var input = $ (esto) .val (); var color = parseColor (entrada); var $ celdas = $ ("# resultado tbody td"); $ cells.eq (0) .attr ("bgcolor", entrada); $ cell.eq (1) .attr ("bgcolor", color); var